from PyQt6.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
    QTableWidget, QTableWidgetItem, QHeaderView, QMessageBox,
    QDialog, QFormLayout, QLineEdit, QTextEdit, QComboBox,
    QDialogButtonBox, QFileDialog
)
from PyQt6.QtGui import QFont, QColor
import os
import logging
from app.utils.logger import get_logger

logger = get_logger(__name__)
import logging
from app.core.queue_manager import QueueManager


class NewScriptDialog(QDialog):
    """新建脚本对话框"""
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("新建脚本")
        self.setMinimumWidth(500)
        self._setup_ui()
    
    def _setup_ui(self):
        """设置UI"""
        layout = QVBoxLayout(self)
        
        # 表单布局
        form_layout = QFormLayout()
        
        # 脚本名称
        self.name_edit = QLineEdit()
        form_layout.addRow("脚本名称:", self.name_edit)
        
        # 脚本类型
        self.type_combo = QComboBox()
        self.type_combo.addItems(["Python", "Shell", "Batch"])
        form_layout.addRow("脚本类型:", self.type_combo)
        
        # 脚本路径
        path_layout = QHBoxLayout()
        self.path_edit = QLineEdit()
        self.path_edit.setReadOnly(True)
        path_layout.addWidget(self.path_edit)
        
        browse_btn = QPushButton("浏览...")
        browse_btn.clicked.connect(self._browse_file)
        path_layout.addWidget(browse_btn)
        
        form_layout.addRow("脚本路径:", path_layout)
        
        # 脚本描述
        self.desc_edit = QTextEdit()
        self.desc_edit.setMaximumHeight(100)
        form_layout.addRow("脚本描述:", self.desc_edit)
        
        layout.addLayout(form_layout)
        
        # 按钮
        button_box = QDialogButtonBox(
            QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
        )
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        layout.addWidget(button_box)
    
    def _browse_file(self):
        """浏览文件"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择脚本文件", "",
            "脚本文件 (*.py *.sh *.bat);;所有文件 (*.*)"
        )
        if file_path:
            self.path_edit.setText(file_path)
    
    def get_script_data(self):
        """获取脚本数据"""
        return {
            "name": self.name_edit.text(),
            "type": self.type_combo.currentText(),
            "path": self.path_edit.text(),
            "description": self.desc_edit.toPlainText()
        }


class EditScriptDialog(QDialog):
    """编辑脚本对话框"""

    def __init__(self, script_data, parent=None):
        super().__init__(parent)
        self.script_data = script_data
        self.setWindowTitle("编辑脚本")
        self.setMinimumWidth(500)
        self._setup_ui()

    def _setup_ui(self):
        """设置UI"""
        layout = QVBoxLayout(self)

        # 表单布局
        form_layout = QFormLayout()

        # 脚本名称
        self.name_edit = QLineEdit(self.script_data["name"])
        form_layout.addRow("脚本名称:", self.name_edit)

        # 脚本类型
        self.type_combo = QComboBox()
        self.type_combo.addItems(["Python", "Shell", "Batch"])
        self.type_combo.setCurrentText(self.script_data["type"])
        form_layout.addRow("脚本类型:", self.type_combo)

        # 脚本路径
        path_layout = QHBoxLayout()
        self.path_edit = QLineEdit(self.script_data["path"])
        self.path_edit.setReadOnly(True)
        path_layout.addWidget(self.path_edit)

        browse_btn = QPushButton("浏览...")
        browse_btn.clicked.connect(self._browse_file)
        path_layout.addWidget(browse_btn)

        form_layout.addRow("脚本路径:", path_layout)

        # 脚本描述
        self.desc_edit = QTextEdit(self.script_data["description"])
        self.desc_edit.setMaximumHeight(100)
        form_layout.addRow("脚本描述:", self.desc_edit)

        layout.addLayout(form_layout)

        # 按钮
        button_box = QDialogButtonBox(
            QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
        )
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        layout.addWidget(button_box)

    def _browse_file(self):
        """浏览文件"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择脚本文件", "",
            "脚本文件 (*.py *.sh *.bat);;所有文件 (*.*)"
        )
        if file_path:
            self.path_edit.setText(file_path)

    def get_script_data(self):
        """获取脚本数据"""
        return {
            "name": self.name_edit.text(),
            "type": self.type_combo.currentText(),
            "path": self.path_edit.text(),
            "description": self.desc_edit.toPlainText()
        }


class ScriptsPage(QWidget):
    """脚本管理页面"""

    def __init__(self, config, database=None, task_scheduler=None):
        """初始化脚本管理页面

        Args:
            config: 应用配置
            database: 数据库实例
            task_scheduler: 任务调度器实例
        """
        super().__init__()
        self.config = config
        self.database = database
        self.task_scheduler = task_scheduler
        self.scripts = []  # 脚本列表
        self._init_ui()
        self._load_scripts()

    def _init_ui(self):
        """初始化UI"""
        # 创建主布局
        layout = QVBoxLayout(self)
        layout.setContentsMargins(20, 20, 20, 20)

        # 添加标题
        title = QLabel("脚本管理")
        title.setFont(QFont("Arial", 16))
        layout.addWidget(title)

        # 添加工具栏
        toolbar = QHBoxLayout()
        
        # 新建脚本按钮
        new_btn = QPushButton("新建脚本")
        new_btn.clicked.connect(self._create_script)
        toolbar.addWidget(new_btn)
        
        # 编辑脚本按钮
        edit_btn = QPushButton("编辑脚本")
        edit_btn.clicked.connect(self._edit_script)
        toolbar.addWidget(edit_btn)
        
        # 删除脚本按钮
        delete_btn = QPushButton("删除脚本")
        delete_btn.clicked.connect(self._delete_script)
        toolbar.addWidget(delete_btn)
        
        toolbar.addStretch()
        layout.addLayout(toolbar)

        # 添加脚本列表
        self.script_table = QTableWidget()
        self.script_table.setColumnCount(5)
        headers = ["ID", "名称", "类型", "路径", "描述", "队列状态"]
        self.script_table.setHorizontalHeaderLabels(headers)
        self.script_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
        self.script_table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.ResizeToContents)
        self.script_table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
        self.script_table.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeMode.ResizeToContents)
        self.script_table.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeMode.ResizeToContents)
        self.script_table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
        self.script_table.setSelectionMode(QTableWidget.SelectionMode.SingleSelection)
        layout.addWidget(self.script_table)

    def _load_scripts(self):
        """从数据库加载脚本列表"""
        if self.database:
            try:
                # 从数据库加载脚本列表
                self.scripts = self.database.get_scripts()
                logger.info(f"已从数据库加载 {len(self.scripts)} 个脚本")
            except Exception as e:
                logger.error(f"从数据库加载脚本失败: {str(e)}")
                # 加载失败时使用空列表
                self.scripts = []
        else:
            logger.warning("数据库实例未初始化，无法加载脚本")
            self.scripts = []
            
        self._update_script_table()

    def _update_script_table(self):
        """更新脚本表格"""
        self.script_table.setRowCount(0)
        for script in self.scripts:
            row = self.script_table.rowCount()
            self.script_table.insertRow(row)
            self.script_table.setItem(row, 0, QTableWidgetItem(str(script.id)))
            self.script_table.setItem(row, 1, QTableWidgetItem(script.name))
            self.script_table.setItem(row, 2, QTableWidgetItem(script.script_type))
            # 内容太长，只显示前30个字符
            content_preview = script.content[:30] + "..." if len(script.content) > 30 else script.content
            self.script_table.setItem(row, 3, QTableWidgetItem(content_preview))
            self.script_table.setItem(row, 4, QTableWidgetItem(script.description or ""))
            
            # 获取队列状态
            status = self.get_queue_status().get(script.id, "未在队列")
            status_item = QTableWidgetItem(status)
            self.script_table.setItem(row, 5, status_item)
            
            # 如果脚本在队列中,设置状态单元格的背景色
            if status != "未在队列":
                status_item.setBackground(QColor("#FFA500"))  # 橙色背景

    def _create_script(self):
        """创建新脚本"""
        dialog = NewScriptDialog(self)
        if dialog.exec() == QDialog.DialogCode.Accepted:
            script_data = dialog.get_script_data()
            
            # 验证输入
            if not script_data["name"]:
                QMessageBox.warning(self, "错误", "请输入脚本名称")
                return
            
            if not script_data["path"]:
                QMessageBox.warning(self, "错误", "请选择脚本文件")
                return
            
            if not os.path.exists(script_data["path"]):
                QMessageBox.warning(self, "错误", "脚本文件不存在")
                return
            
            try:
                # 读取脚本文件内容
                with open(script_data["path"], "r", encoding="utf-8") as f:
                    content = f.read()
                
                # 准备数据库存储数据
                db_script_data = {
                    "name": script_data["name"],
                    "description": script_data["description"],
                    "content": content,
                    "script_type": script_data["type"]
                }
                
                # 保存到数据库
                if self.database:
                    script = self.database.create_script(db_script_data)
                    logger.info(f"已创建新脚本: {script.name} (ID: {script.id})")
                    self._load_scripts()  # 重新加载脚本列表
                    QMessageBox.information(self, "成功", "脚本创建成功")
                else:
                    logger.error("数据库实例未初始化，无法创建脚本")
                    QMessageBox.warning(self, "错误", "数据库连接失败，无法创建脚本")
            except Exception as e:
                logger.error(f"创建脚本失败: {str(e)}")
                QMessageBox.warning(self, "错误", f"创建脚本失败: {str(e)}")

    def _edit_script(self):
        """编辑脚本"""
        current_row = self.script_table.currentRow()
        if current_row < 0:
            QMessageBox.warning(self, "警告", "请先选择要编辑的脚本")
            return
        
        # 获取当前脚本数据
        script = self.scripts[current_row]
        
        # 准备对话框数据
        dialog_data = {
            "name": script.name,
            "type": script.script_type,
            "path": "",  # 编辑时不显示路径
            "description": script.description or ""
        }
        
        # 打开编辑对话框
        dialog = EditScriptDialog(dialog_data, self)
        if dialog.exec() == QDialog.DialogCode.Accepted:
            new_data = dialog.get_script_data()
            
            # 验证输入
            if not new_data["name"]:
                QMessageBox.warning(self, "错误", "请输入脚本名称")
                return
            
            try:
                # 如果选择了新文件，读取文件内容
                content = script.content
                if new_data["path"] and os.path.exists(new_data["path"]):
                    with open(new_data["path"], "r", encoding="utf-8") as f:
                        content = f.read()
                
                # 准备数据库更新数据
                db_script_data = {
                    "name": new_data["name"],
                    "description": new_data["description"],
                    "content": content,
                    "script_type": new_data["type"]
                }
                
                # 更新数据库
                if self.database:
                    updated_script = self.database.update_script(script.id, db_script_data)
                    logger.info(f"已更新脚本: {updated_script.name} (ID: {updated_script.id})")
                    self._load_scripts()  # 重新加载脚本列表
                    QMessageBox.information(self, "成功", "脚本更新成功")
                else:
                    logger.error("数据库实例未初始化，无法更新脚本")
                    QMessageBox.warning(self, "错误", "数据库连接失败，无法更新脚本")
            except Exception as e:
                logger.error(f"更新脚本失败: {str(e)}")
                QMessageBox.warning(self, "错误", f"更新脚本失败: {str(e)}")

    def _delete_script(self):
        """删除脚本"""
        current_row = self.script_table.currentRow()
        if current_row < 0:
            QMessageBox.warning(self, "警告", "请先选择要删除的脚本")
            return
        
        # 获取当前脚本
        script = self.scripts[current_row]
        script_name = script.name
        
        reply = QMessageBox.question(
            self, "确认", f"确定要删除脚本 '{script_name}' 吗？",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            try:
                # 从数据库删除
                if self.database:
                    success = self.database.delete_script(script.id)
                    if success:
                        logger.info(f"已删除脚本: {script_name} (ID: {script.id})")
                        self._load_scripts()  # 重新加载脚本列表
                        QMessageBox.information(self, "成功", "脚本删除成功")
                    else:
                        logger.error(f"删除脚本失败: {script_name}")
                        QMessageBox.warning(self, "错误", "删除脚本失败")
                else:
                    logger.error("数据库实例未初始化，无法删除脚本")
                    QMessageBox.warning(self, "错误", "数据库连接失败，无法删除脚本")
            except Exception as e:
                logger.error(f"删除脚本失败: {str(e)}")
                QMessageBox.warning(self, "错误", f"删除脚本失败: {str(e)}")

    def get_queue_status(self):
        """获取队列中所有脚本的状态"""
        queue_status = {}
        try:
            # 从队列管理器获取当前队列状态
            if self.task_scheduler:
                queue_items = self.task_scheduler.queue_manager.get_all_items()
                for item in queue_items:
                    if "script_id" in item and "status" in item:
                        queue_status[item["script_id"]] = item["status"]
            else:
                # 如果任务调度器未初始化，尝试直接使用队列管理器
                queue_items = QueueManager().get_all_items()
                for item in queue_items:
                    if "script_id" in item and "status" in item:
                        queue_status[item["script_id"]] = item["status"]
        except Exception as e:
            logger.error(f"获取队列状态失败: {e}")
        return queue_status

    def get_all_scripts(self):
        """获取所有脚本列表，供其他页面使用"""
        if self.database:
            return self.database.get_scripts()
        return self.scripts

    def get_script_names(self):
        """获取所有脚本名称列表，供其他页面使用"""
        if self.database:
            return self.database.get_script_names()
        return [script.name for script in self.scripts]